import { PureComponent } from 'react';
import {Card, Row, Col, Avatar, Input, Select, Form, Button, Tooltip, Divider, Spin} from 'antd';
import React from 'react';
import { connect } from 'umi';
import Meta from 'antd/es/card/Meta';
import { history } from '@@/core/history';
import { formatMessage } from '@@/plugin-locale/localeExports';
import { queryByCode } from '@/pages/BlogEdit/service';
import styles from '@/pages/common.less';
import 'animate.css';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import InfiniteScroll from 'react-infinite-scroll-component';
const { Search } = Input;
const { Option } = Select;

class BlogSpace extends PureComponent {
  state = {
    formValues: {},
    blogLabel: null,
    blogType: null,
    pageSize: 9,
    page: 3,
    data: [],
    loading: false,
    num: 0,
    total: 0
  };

  componentDidMount() {
    const { dispatch } = this.props;
    const { pageSize } = this.state;
    dispatch({
      type: 'blogSpace/fetch',
      payload: {
        status: 2,
        pageSize: pageSize
      },
    }).then(res => {
      this.setState({
        data: res.data.list,
        total: res.data.pagination.total
      })
    })
    queryByCode({ code: 'blogLabel' }).then((res) => {
      if (res.status == 200) {
        this.setState({ blogLabel: res.data.value });
      }
    });
    queryByCode({ code: 'blogType' }).then((res) => {
      if (res.status == 200) {
        this.setState({ blogType: res.data.value });
      }
    });
    this.formRef = React.createRef();
  }

  handleSearch = (e) => {
    const { dispatch } = this.props;
    const { pageSize } = this.state;
    const values = {
      ...e,
    };
    values.type = values.type ? values.type.join(',') : null;
    values.label = values.label ? values.label.join(',') : null;
    this.setState({
      formValues: values,
    });
    dispatch({
      type: 'blogSpace/fetch',
      payload: {
        ...values,
        status: 2,
        pageSize: pageSize
      },
    }).then(res => {
      if (res.status == 200){
        this.setState({data: res.data.list, total: res.data.pagination.total});
      }
    })
  };

  handleFormReset = () => {
    const { dispatch } = this.props;
    this.formRef.current.resetFields();
    this.setState({
      formValues: {},
      pageSize: 9,
      page: 3
    });
    dispatch({
      type: 'blogSpace/fetch',
      payload: {
        status: 2,
        pageSize: 9
      }
    }).then(res => {
      if (res.status == 200) {
        this.setState({data: res.data.list, total: res.data.pagination.total});
      }
    })
  };

  onSearch = (e) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'blogSpace/fetch',
      payload: {
        status: 2,
        title: e,
        pageSize: 9
      },
    }).then(res => {
      if (res.status == 200) {
        this.setState({data: res.data.list, total: res.data.pagination.total});
      }
    })
  };

  toBlogInfo = (id) => {
    history.push('/blogInfo?id=' + id);
  };

  animateIn = (index) => {
    document.getElementsByClassName(`blog_${index}`)[0].classList.add('animate__headShake');
  };

  animateOut = (index) => {
    document.getElementsByClassName(`blog_${index}`)[0].classList.remove('animate__headShake');
  };

  isElementInViewport = (el) => {
    const rect = el.getBoundingClientRect()
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <=
      (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <=
      (window.innerWidth || document.documentElement.clientWidth)
    )
  };

  loadMoreData = () => {
    const { dispatch } = this.props;
    const { formValues, data, loading, page, num } = this.state;
    if (loading && num == 0){
      return;
    }
    this.setState({loading: true});
    dispatch({
      type: 'blogSpace/fetch',
      payload: {
        ...formValues,
        status: 2,
        pageSize: 3,
        currentPage: page + 1
      },
    }).then(res => {
      this.setState({
        data: ([...data, ...res.data.list])
      }, () => {
        this.setState({loading: false, page: page + 1, num: num + 1});
      })
    })
  }

  render() {
    const {
      loading
    } = this.props;
    const { data } = this.state;
    const { blogType, blogLabel, total } = this.state;

    return (
      <>
        <Card>
          <Form ref={this.formRef} onFinish={this.handleSearch}>
            <Row style={{ padding: '0 50px 0 120px' }}>
              <Col span={6}>
                <Form.Item label="标题" name="title">
                  <Search
                    placeholder="搜索博客"
                    style={{ width: '100%' }}
                    onSearch={this.onSearch}
                  />
                </Form.Item>
              </Col>
              <Col span={6} offset={1}>
                <Form.Item label="分类" name="type">
                  <Select mode="tags" style={{ width: '100%' }} placeholder="分类搜索">
                    {blogType &&
                      blogType.length > 0 &&
                      blogType.split(',').map((item) => <Option key={item}>{item}</Option>)}
                  </Select>
                </Form.Item>
              </Col>
              <Col span={6} offset={1}>
                <Form.Item label="标签" name="label">
                  <Select mode="tags" style={{ width: '100%' }} placeholder="标签搜索">
                    {blogLabel &&
                      blogLabel.length > 0 &&
                      blogLabel.split(',').map((item) => <Option key={item}>{item}</Option>)}
                  </Select>
                </Form.Item>
              </Col>
              <Col md={4} sm={24}>
                <span className={styles.submitButtons} style={{ textAlign: 'right' }}>
                  <Button style={{ marginLeft: 10 }} type="primary" htmlType="submit">
                    {formatMessage({ id: 'app.common.search' })}
                  </Button>
                  <Button style={{ marginLeft: 10 }} onClick={this.handleFormReset} type="primary">
                    {formatMessage({ id: 'app.common.reset' })}
                  </Button>
                </span>
              </Col>
            </Row>
          </Form>
        </Card>
        <Card bordered={false} className='scrollableCard'>
          <ReactCSSTransitionGroup
            transitionEnter={true}
            transitionLeave={true}
            transitionEnterTimeout={2500}
            transitionLeaveTimeout={1500}
            transitionName="animate"
          >
            <InfiniteScroll
              style={{ padding: '0 9% 0 10%' }}
              dataLength={total}
              next={this.loadMoreData}
              hasMore={data.length != total}
              loader={<Spin style={{ marginLeft: '48.5%', marginTop: '2%' }} tip='加载中...'/>}
              endMessage={<Divider plain>到底了哦(o･ｪ･o)</Divider>}
              scrollableTarget="scrollableCard"
            >
              <Row>
              {data &&
                data.length > 0 &&
                data.map((item, index) => (
                  <Col span={8} style={index > 2 && { marginTop: '3%' }}>
                    <Card
                      className={`animate__animated blog_${index}`}
                      key={`blog_${index}`}
                      // style={{ width: 350 }}
                      style={ { marginLeft: (index % 3 > 1) ? '3%' : '0', marginRight: (index % 3 < 1) ? '3%' : '0' }}
                      cover={<img alt="暂无封面" src={item.cover} style={{ height: '210px' }} />}
                      bordered={true}
                      loading={loading}
                      hoverable
                      onClick={() => this.toBlogInfo(item.id)}
                      onMouseEnter={() => this.animateIn(index)}
                      onMouseLeave={() => this.animateOut(index)}
                    >
                      <Meta
                        avatar={<Avatar src={item.avatar} />}
                        title={item.loginName}
                        description={
                          <>
                            <Row>
                              <Col span={24} style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                                <Tooltip title={item.title}>
                                  <a onClick={() => this.toBlogInfo(item.id)}>{item.title}</a>
                                </Tooltip>
                              </Col>
                            </Row>
                            <Row>
                              <Col span={24}>
                                <span style={{ color: 'lightgray', fontSize: '12px' }}>{item.createTime}</span>
                              </Col>
                            </Row>
                          </>
                        }
                      />
                    </Card>
                  </Col>
                ))}
              </Row>
            </InfiniteScroll>
          </ReactCSSTransitionGroup>
        </Card>
      </>
    );
  }
}

export default connect(({ blogSpace, loading }) => ({
  blogSpace,
  loading: loading.effects['blogSpace/fetch'],
}))(BlogSpace);
